/* 
    Page 处理下拉刷新与触底加载
    王欢
    2020/5/21
    ## 注意
       默认开启下拉刷新 但是要在 json配置开启  enablePullDownRefresh:true
    ### vant tabs demo
    <van-tabs 
        sticky="{{ true }}"
        active="{{ v_tabsIndex }}" 
        swipeable="{{ true }}" 
        animated="{{ true }}" 
        bind:change="v_tabsChange" 
        data-refresh_auto="{{ true }}" 
        class="__van-tabsCover"
    >
        <van-tab 
            wx:for="{{ v_tabsInfo }}" 
            wx:key="index" 
            title="{{ item.title }}" 
            data-index="{{ index }}"
        >
            <!-- 列表视图   -->
            <view class="item" 
                wx:for="{{ v_tabsInfo[v_tabsIndex].list }}"
                wx:for-index="listItemIndex"
                wx:key="listItemIndex"
            >item view</view>
            <!-- 提示   -->
            <block>
                <view wx:if="{{ v_tabsInfo[v_tabsIndex].end }}">
                    <van-empty description="当前列表没有内容哦" wx:if="{{ !v_tabsInfo[v_tabsIndex].list.length }}" />
                    <block wx:else>
                        <van-divider wx:if="{{ v_tabsEndNoticShow && v_tabsInfo[v_tabsIndex].count !== 1 }}" contentPosition="center">
                            {{ v_tabsEndNoticText }}
                        </van-divider>
                    </block>
                </view>
                <van-loading size="24px" wx:if="{{ v_tabsReachBottomLoading }}" class="__van-tabsLoading">
                    {{ v_tabsReachBottomLoadingText }}
                </van-loading>
            </block>
        </van-tab>
    </van-tabs>
*/
/* 2021/8/2 
    新添 scroll-view item的居中滑动
    配置
        ##必要配置
         // scroll-view 元素 class 或 id
        v_scrollClass:""
         //  scroll-view  子元素 class
        v_scrollItemClass:""
        可选配置
            //自定义scroll-left 存储变量
        v_scrollLeftModel

*/
const mixin_scrollToView = require("./mixin_scrollToView");
module.exports = {

    data: {
        /* ----------------  常用配置项 start  ---------------- */

        // tabs数据列表
        v_tabsInfo: [{
            //标题
            title: "全部"
            // query type
            , type: 0
            // 页码
            , count: 1
            // 数据是否加载完
            , end: false
            // 数据列表
            , list: []
            /* 
            // 置顶数据
            , topList: []
            // 置顶数据合并 key
            , topKey: "" 
            */
        }]
        // tabs索引
        , v_tabsIndex: 0
        // tabs http path
        , v_tabsHttpPath: ""
        // 列表初次加载生命周期事件 - onLoad onShow custom自定义
        , v_tabsInitLife: "custom"
        // tabs http query转换设置
        , v_tabsHttpKeys: {
            type: "type"
            , count: "page"
            , v_tabsPageLimit: "limit"
        }
        // tabs一页数据量
        , v_tabsPageLimit: 10
        // 是否使用 vant tabs
        , v_setVantAuto: false
        // 是否开启  下拉刷新
        , v_openPullDownRefresh: false
        // 是否开启  触底加载
        , v_openReachBottom: true
        // 是否开启滑动切换
        , v_openScrollToView: false
        /* ---------------- 常用配置项 end  ---------------- */
        //scroll-view 元素 class 或 id
        , v_scrollClass: ""
        // scroll-view  子元素 class
        , v_scrollItemClass: ""
        // scroll-view scroll-left载入的model
        , v_scrollLeftModel: "v_scrollLeft"
        // scroll-vew data  scrollleft -- model
        , v_scrollLeft: ""
        // 切换tabs是否自动刷新
        , v_tabsRefreshAuto: true
        // tabs 是否处于触底加载事件中
        , v_tabsReachBottomLoading: false
        // tabs 当前页码加载完毕 提示
        , v_tabsEndNoticText: "已经到底了哦"
        // tabs 当前页码加载完毕 提示是否显示
        , v_tabsEndNoticShow: true
        // tabs 触底加载文本提示
        , v_tabsReachBottomLoadingText: "loading..."
        // 列表刷新延迟回调时间
        , v_tabsPullDownRefreshCallbackTime: 500
        // 列表刷新成功的提示
        , v_tabsPullDownRefreshNotic: {
            success: "列表刷新成功！"
            , fail: "列表刷新失败！"
        }

    }
    , mixins: [mixin_scrollToView]
    /* 
        ,computed:{
            // ## tabs http query 合并的参数
            v_tabsHttpQueryAssignInfo(){
                return {};
        }
    } */

    , onLoad() {
        this.v_getTabsInitLife("onLoad");
    }
    , onShow() {
        this.v_getTabsInitLife("onShow");
    }
    , onPullDownRefresh() {
        if (this.data.v_openPullDownRefresh) {
            this.v_tabsPullDownRefresh(true);
        }
    }
    , onReachBottom() {
        if (this.data.v_openReachBottom) {
            this.v_tabsReachBottom();
        }
    }
    /* ----------------  必须配置项 start  ---------------- */
    /* 
        自定义处理当前列表参数  每个项目可根据接口单独设置
        list  列表
        end   列表是否加载结束
        传入的值 
            res 接口返回值
            tabsItem    v_tabsInfo[v_tabsIndex] 当前索引对象
            concatAuto  是否拼接  true 拼接 false 赋值
        返回一个新的 当前索引对象
        
    */
    , v_updateTabsItem({
        res
        , tabsItem
        , concatAuto
    }) {
        const page = this;
        //前后台定义 一页数据量
        const { data } = res;
        const { v_tabsPageLimit } = page.data;
        tabsItem.end = data.length < v_tabsPageLimit;
        /* 
            //通过接口返回  总页数
            const { data: { total, list:data } } = res;
            const { count } = tabsItem;
            tabsItem.end = total == 0 || count == total;;
        
        */
        if (concatAuto) {
            tabsItem.list = tabsItem.list.concat(data);
        } else {
            tabsItem.list = data;
        }

        return tabsItem;
    }
    /* ----------------  必须配置项 end  ---------------- */
    /*
        // ## 对 tabsInfo data 进行处理
        ,v_tabsDataTransform( tabsData ){} 
    
    */
    // 置顶数据筛选
    , v_topMerge(navItem) {
        // 置顶数据拼接
        const { topList, topKey, list } = navItem;
        if (topList && topList.length) {
            if (topKey && list.length) {
                const { list } = navItem;

                for (let i = list.length - 1; i >= 0; i--) {
                    let listItem = list[i];
                    let hasTop = topList.some(item => {
                        return item[topKey] == listItem[topKey];
                    })

                    if (hasTop) {
                        list.splice(i, 1);
                    }
                }
            }

            navItem.list.unshift(...topList);
        }
        return navItem;
    }
    // 初次加载
    , v_getTabsInitLife(lifeName) {
        const page = this;
        const { v_tabsRefreshAuto, v_tabsIndex, v_tabsInitLife } = page.data;
        if (v_tabsInitLife && v_tabsInitLife === lifeName) {

            page.v_tabsChange(undefined, {
                tabs_index: v_tabsIndex,
                refresh_auto: v_tabsRefreshAuto
            });
        }
    }
    // 加载分页内容
    , v_getTabsPage(params) {
        const page = this;
        const { v_tabsHttpKeys
            , v_tabsHttpQueryAssignInfo
            , v_tabsHttpPath
        } = page.data;
        const httpQuerys = {};
        Object.keys(v_tabsHttpKeys)
            .forEach(key => {
                const transKey = v_tabsHttpKeys[key];
                if (transKey) {
                    httpQuerys[transKey] = params[key];
                }
            });
        if (v_tabsHttpQueryAssignInfo) {
            Object.assign(httpQuerys, v_tabsHttpQueryAssignInfo);
        }
        // 搜索关键字
        const { searchKeys } = params;
        if (searchKeys) {
            Object.assign(httpQuerys, searchKeys);
        }
        return page.$get(v_tabsHttpPath, httpQuerys);
    }
    // 导航切换
    , v_tabsChange(event, navInfo) {
        const page = this;
        const { v_tabsInfo, v_tabsPageLimit, v_tabsRefreshAuto, v_setVantAuto } = page.data;
        if (!v_tabsInfo.length) {
            throw Error("tabs Error: tabsInfo length is null");
        }
        let v_tabsIndex;
        let refreshAuto = v_tabsRefreshAuto;
        let success;
        let fail;
        // 搜索关键字  Object 类型 
        let searchKeys;
        if (event) {
            let index;
            if (v_setVantAuto) {
                index = event.detail.index;
            } else {
                index = event.currentTarget.dataset.tabs_index;
            }
            v_tabsIndex = index;
            const eventDataset = event.currentTarget.dataset;
            searchKeys = eventDataset.search_keys;
            if ("refresh_auto" in eventDataset) {
                refreshAuto = eventDataset.refresh_auto;
            }
        } else if (navInfo) {
            v_tabsIndex = navInfo.tabs_index;
            searchKeys = navInfo.search_keys;
            success = navInfo.success;
            fail = navInfo.fail;
            if ("refresh_auto" in navInfo) {
                refreshAuto = navInfo.refresh_auto;
            }
        } else {
            throw ReferenceError("tabs Error: tabsChange missing required parameter")
        }
        page.setData({
            v_tabsIndex
        });
        /* 是否滑动切换 */
        const { v_openScrollToView } = page.data;
        // 前提不使用 vant组件
        if (!v_setVantAuto && v_openScrollToView) {
            const { v_scrollClass, v_scrollItemClass, v_scrollLeftModel } = page.data;
            page.scrollIntoView({
                scrollClass: v_scrollClass
                , scrollItemClass: v_scrollItemClass
                , scrollIndex: v_tabsIndex
                , scrollLeftModel: v_scrollLeftModel
            });
        }

        let navItem = v_tabsInfo[v_tabsIndex];
        // 切换加载  条件
        // 强制刷新开启
        //  或者   没有加载完  并且  数据为0
        if (refreshAuto || (
            !navItem.end
            &&
            !navItem.list.length
        )) {
            if (refreshAuto) {
                navItem.count = 1;
            }
            const { type, count } = navItem;
            page.v_getTabsPage({
                type
                , count
                , v_tabsPageLimit
                , searchKeys
            })
                .then(res => {
                    const { v_tabsDataTransform } = page;
                    if (v_tabsDataTransform && typeof v_tabsDataTransform === "function") {
                        list = v_tabsDataTransform(list);
                    }
                    // 处理当前列表数据  是否结束   列表数据赋值
                    navItem = page.v_updateTabsItem({ tabsItem: navItem, res, concatAuto: false });
                    // 处理当前列表  置顶数据   
                    navItem = page.v_topMerge(navItem);
                    page.setData({
                        v_tabsInfo
                    });
                    if (success && typeof success === "function") {
                        success();
                    }
                }).catch(err => {
                    if (fail && typeof fail === "function") {
                        fail(err);
                    } else {
                        page.$fail(err);
                    }
                });
        }

    }
    // tabs 下拉刷新
    , v_tabsPullDownRefresh(noticAuto = true) {
        const page = this;
        const { v_tabsIndex, v_tabsPullDownRefreshCallbackTime } = page.data;
        page.v_tabsChange(undefined, {
            tabs_index: v_tabsIndex
            , refresh_auto: true
            , success() {
                setTimeout(function () {
                    wx.stopPullDownRefresh();
                    if (noticAuto) {
                        const { v_tabsPullDownRefreshNotic } = page.data;
                        page.$log(v_tabsPullDownRefreshNotic.success);
                    }
                }, v_tabsPullDownRefreshCallbackTime);
            }
            , fail(err) {
                setTimeout(function () {
                    wx.stopPullDownRefresh();
                    if (noticAuto) {
                        const { v_tabsPullDownRefreshNotic } = page.data;
                        page.$fail(v_tabsPullDownRefreshNotic.fail || err);
                    }
                }, v_tabsPullDownRefreshCallbackTime);
            }
        });
    }
    // tabs 触底加载
    , v_tabsReachBottom() {
        const page = this;
        let { v_tabsInfo, v_tabsIndex, v_tabsPageLimit, v_tabsReachBottomLoading } = page.data;
        if (!v_tabsInfo.length) {
            throw Error("tabs Error: tabsInfo length is null");
        }
        let navItem = v_tabsInfo[v_tabsIndex];
        const { count, end, type } = navItem;
        // 如果处于触底加载事件中  退出
        if (v_tabsReachBottomLoading) {
            return false;
        }
        if (end) {
            return false;
        } else {
            v_tabsReachBottomLoading = true;
            page.setData({
                v_tabsReachBottomLoading
            });
            const nextcount = count + 1;
            page.v_getTabsPage({
                type
                , count: nextcount
                , v_tabsPageLimit
            }).then(res => {
                // 处理当前列表数据  是否结束   列表数据赋值
                navItem = page.v_updateTabsItem({ tabsItem: navItem, res, concatAuto: true });
                navItem.count = nextcount;
                v_tabsReachBottomLoading = false;
                // navItem = page.v_topMerge( navItem );
                page.setData({
                    v_tabsInfo
                    , v_tabsReachBottomLoading
                });
            }).catch(err => {
                v_tabsReachBottomLoading = false;
                page.setData({
                    v_tabsReachBottomLoading
                });
                page.$fail(err);
            });
        }
    }

}